package reesoft.common.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 公共的类操作单元
 *
 * Created by reesoft on 2017-08-31
 */
public class ClassUtil
{
    /**
     * 把对象的所有属性和值（包括父类的）取出，生成映射集合
     *
     * @param object 对象
     * @param clazz 类
     * @param attributeMap 汇总属性的映射集合，如果不为 null，返回值仍是该映射
     * @return 如果 attributeMap 参数不为 null，则返回 attributeMap，否则返回新的实例
     */
    public static Map<String, String> toAttributeMap(final Object object, final Class clazz, Map<String, String> attributeMap)
    {
        if (attributeMap == null)
        {
            attributeMap = new HashMap<>();
        }

        if (object == null || clazz == null)
        {
            return attributeMap;
        }

        if (!clazz.getSuperclass().equals(Object.class))
        {
            attributeMap = toAttributeMap(object, clazz.getSuperclass(), attributeMap);
        }

        for (Field field : clazz.getDeclaredFields())
        {
            try
            {
                attributeMap.put(field.getName(), getFieldValue(object, clazz, field));
            }
            catch (ReflectiveOperationException e)
            {
                e.printStackTrace();
            }
        }

        return attributeMap;
    }

    /**
     * 取得对象的属性值
     *
     * @param object 对象
     * @param clazz 类
     * @param field 属性字段
     * @return 转换为字符串类型的属性值
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public static String getFieldValue(final Object object, final Class clazz, final Field field)
            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException
    {
        String fieldName = field.getName();

        String methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);

        Method method = clazz.getMethod(methodName);

        return ConvertUtil.toString(method.invoke(object), null);
    }
}
